/**
 * Description: 创建一个守护进程
 * File: make_deamon.c |Time: 2021-04-08 19:16
 */

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>

#define DEAMON_DIR "/home/b/work/c/21_progress"

int main(int argc, char *argv[])
{
    // 1. 创建一个孤儿进程
    printf("start create deamon progress.\n");
    pid_t pid = fork();

    if (pid == 0) {

        // 2. 改变进程创建文件掩码
        mode_t old_mask = umask(0000);
        printf("[son] previous mask: %#03o\n", old_mask);
        printf("[son] change make code to 000.\n");
        
        // 3. 设置新的会话ID
        pid_t new_sid = setsid();
        if (-1 == new_sid) {
            perror("[son] setsid");
            return -1;
        } else {
            printf("[son] set new sid: %d\n", new_sid);
        }
        
        // 4. 改变工作目录
        if (-1 == chdir(DEAMON_DIR)) {
            perror("[son] chdir");
            return -1;
        } else {
            printf("[son] change working directory to %s\n", DEAMON_DIR);
        }
        // 5. 开启日志
        char log_path[100] = {0};
        sprintf(log_path, "%s/deamon.log", DEAMON_DIR);
        FILE * fp = fopen(log_path, "w");
        if (NULL == fp) {
            perror("[son] fopen");
            return -1;
        }

        char buf[100] = {0};
        sprintf(buf, "[son] try to log pid: %d\n", getpid());
        printf("[son] buf = %s\n", buf);
        printf("[son] buf len = %lu\n", strlen(buf));

        if (fwrite(buf, 1, strlen(buf), fp) < strlen(buf)) {
            printf("[son] fwrite error: %lu\n", strlen(buf));
            return -1;
        } else {
            fflush(NULL);
            printf("[son] write file successful.\n");
        }

        // 6. 关闭系统默认打开的文件描述符
        close(0);
        close(1);
        close(2);

        while(1) {
            // do something here...
            time_t time_sec = time(NULL);
            struct tm *time = localtime(&time_sec);
            sprintf(buf, "[%04d-%02d-%02d %02d:%02d:%02d] pid:%d log.\n", 
                    time->tm_year + 1900,
                    time->tm_mon + 1,
                    time->tm_mday,
                    time->tm_hour,
                    time->tm_min,
                    time->tm_sec,
                    getpid()
                    );
            fwrite(buf, 1, strlen(buf), fp);
            fflush(NULL);
            sleep(1);
        }
    } else {
        printf("[father] I am father(%d), I will quit.\n", getpid());
        printf("[father] the deamon pid is: %d\n", pid);
    }

    return 0;
}


